package com.ouc.pampas;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.io.TemplateLoader;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps;
import com.ouc.openplatform.pampas.UserUtil;
import java.io.FileNotFoundException;
import java.util.Map;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class HandlebarsEngine
{
  private static final Logger log = LoggerFactory.getLogger(HandlebarsEngine.class);
  private Handlebars handlebars;
  private Invoker invoker;
  private final LoadingCache<String, Optional<Template>> caches;
  private ConfigManager configManager;
  
  @Autowired
  public HandlebarsEngine(Invoker invoker, Setting setting, ConfigManager configManager, ServletContext servletContext)
  {
    this.invoker = invoker;
    TemplateLoader templateLoader = new GreatTemplateLoader(servletContext, "/views", ".hbs");
    this.handlebars = new Handlebars(templateLoader);
    this.caches = initCache(!setting.isDevMode());
    this.configManager = configManager;
  }
  
  private LoadingCache<String, Optional<Template>> initCache(boolean buildCache)
  {
    return null;
  }
  
  public <T> void registerHelper(String name, Helper<T> helper)
  {
    this.handlebars.registerHelper(name, helper);
  }
  
  public void registerHelpers(Map<String, Helper<?>> helpers)
  {
    for (String key : helpers.keySet()) {
      this.handlebars.registerHelper(key, (Helper)helpers.get(key));
    }
  }
  
  public String execInline(String templateStr, Map<String, Object> params)
  {
    return execInline(templateStr, params, null);
  }
  
  public String execInline(String templateStr, Map<String, Object> params, String cacheKey)
  {
    try
    {
      if (params == null) {
        params = Maps.newHashMap();
      }
      Template template;
      if ((this.caches == null) || (cacheKey == null)) {
        template = this.handlebars.compileInline(templateStr);
      } else {
        template = (Template)((Optional)this.caches.getUnchecked("inline/" + cacheKey)).orNull();
      }
      if (template == null)
      {
        log.error("failed to exec handlebars' template:{}", templateStr);
        return "";
      }
      return template.apply(params);
    }
    catch (Exception e)
    {
      log.error("出错了:exec handlebars' template failed: {},cause:{}", templateStr, Throwables.getStackTraceAsString(e));
    }
    return "";
  }
  
  public String execPath(String path, Map<String, Object> params, boolean isComponent)
    throws FileNotFoundException
  {
    try
    {
      if (params == null) {
        params = Maps.newHashMap();
      }
      Template template;
      if (isComponent)
      {
        if (this.caches == null) {
          template = this.handlebars.compile("component:" + path);
        } else {
          template = (Template)((Optional)this.caches.getUnchecked("component:" + path)).orNull();
        }
        params.put("_COMP_PATH_", path);
      }
      else
      {
        if (this.caches == null) {
          template = this.handlebars.compile(path);
        } else {
          template = (Template)((Optional)this.caches.getUnchecked(path)).orNull();
        }
      }
      if (template == null)
      {
        return "";
      }
      params.put("_USER_", UserUtil.getCurrentUser());
      params.put("_HREF_", this.configManager.getFrontConfig().getCurrentHrefs(ThreadVars.getHost()));
      params.put("_LOCALE_", ThreadVars.getLocale());
      return template.apply(params);
    }
    catch (Exception e)
    {
      Throwables.propagateIfInstanceOf(e, FileNotFoundException.class);
      log.error("出错了---execute handlebars' template(path={}),cause:{} ", path, Throwables.getStackTraceAsString(e));
    }
    return "";
  }
  
  public String execComponent(com.ouc.pampas.Component component, Map<String, Object> context)
  {
    if (!Strings.isNullOrEmpty(component.getService()))
    {
      Object object = null;
      try
      {
        object = this.invoker.invoke(component.getService(), context);
      }
      catch (Exception e)
      {
        log.error("error when invoke component, component: {}", component, e);
        context.put("_ERROR_", e.getMessage());
      }
      context.put("_DATA_", object);
    }
    try
    {
      return execPath(component.getPath(), context, true);
    }
    catch (Exception e)
    {
      log.error("failed to execute handlebars' template(path={}),cause:{} ", component.getPath(), Throwables.getStackTraceAsString(e));
    }
    return "";
  }
}
